﻿#define _CRT_SECURE_NO_WARNINGS 1


//#include <stdio.h>
//int main()
//{
//    int i,j,k,n;
//    int p,q;
//    int a[20][20];
//    int count;
//    scanf("%d",&n);
//    count=0;
//    p=0;
//    q=n-1;
//    while(count<n*n)
//    {
//        for(i=p;i<=q;i++)
//                a[p][i]=++count;
//        for(i=p+1;i<=q;i++)
//                a[i][q]=++count;
//        for(i=q-1;i>=p;i--)
//                a[q][i]=++count;
//        for(i=q-1;i>=p+1;i--)
//                a[i][p]=++count;
//           ++p;
//           --q;
//
//    }
//   for(i=0;i<n;i++)
//   {
//       for(j=0;j<n;j++)
//               printf("%4d ",a[i][j]);
//       printf("\n");
//   }
//
//}
//
////回型矩阵终于自己写出来了！！！

/*
描述
给你一个整数n，输出n∗n的蛇形矩阵。
输入描述：
输入一行，包含一个整数n
输出描述：
输出n行，每行包含n个正整数，通过空格分隔。

1<=n<=1000
示例1
输入：
4
复制
输出：
1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16
*/
//#include <stdio.h>
//
//int main()
//{
//    int n = 0; 
//    int count = 2;
//    int row = 0;
//    int col = 0, time = 0;
//    int arr[1000][1000] = { 0 };
//    scanf("%d", &n);
//    arr[0][0] = 1;
//    while (count <= n * n)
//    {
//        if (col < n - 1)
//        {
//            col++;
//            time++;
//        }
//        else
//        {
//            row++;
//            time--;
//        }
//        arr[row][col] = count++;
//        for (int i = 0; i < time; i++)
//        {
//            row++;
//            col--;
//            arr[row][col] = count++;
//        }
//        if (row < n - 1)
//        {
//            time++;
//            row++;
//        }
//        else
//        {
//            time--;
//            col++;
//        }
//        arr[row][col] = count++;
//        for (int i = 0; i < time; i++)
//        {
//            row--;
//            col++;
//            arr[row][col] = count++;
//        }
//    }
//    for (int i = 0; i < n; i++)
//    {
//        for (int j = 0; j < n; j++)
//        {
//            printf("%d ", arr[i][j]);
//        }
//        printf("\n");
//    }
//    return 0;
//}

/*
描述
给出两幅相同大小的黑白图像（用0-1矩阵）表示，求它们的相似度。若两幅图像在相同位置上的像素点颜色相同，则称它们在该位置具有相同的像素点。两幅图像的相似度定义为相同像素点数占总像素点数的百分比。

输入描述：
第一行包含两个整数m和n，表示图像的行数和列数，用单个空格隔开。1≤m≤100, 1≤n≤100。之后m行，每行n个整数0或1，表示第一幅黑白图像上各像素点的颜色，相邻两个数用单个空格隔开。之后m行，每行n个整数0或1，表示第二幅黑白图像上各像素点的颜色，相邻两个数用单个空格隔开。
输出描述：
一个实数，表示相似度(以百分比的形式给出)，精确到小数点后两位。
示例1
输入：
3 3
1 0 1
0 0 1
1 1 0
1 1 0
0 0 1
0 0 1
复制
输出：
44.44
*/
//#include <stdio.h>
//
//int main()
//{
//    int m = 0, n = 0;
//    int count = 0;
//    int arr1[100][100] = { 0 };
//    int arr2[100][100] = { 0 };
//    scanf("%d%d", &m, &n);
//    for (int i = 0; i < m; i++)
//    {
//        for (int j = 0; j < n; j++)
//        {
//            scanf("%d", &arr1[i][j]);
//        }
//    }
//    for (int i = 0; i < m; i++)
//    {
//        for (int j = 0; j < n; j++)
//        {
//            scanf("%d", &arr2[i][j]);
//            if (arr1[i][j] == arr2[i][j])
//                count++;
//        }
//    }
//    float c = count * 100.0 / (m * n);
//    printf("%.2f", c);
//    return 0;
//}



/*本题要求实现一个计算非负整数阶乘的简单函数，使得可以利用该函数，计算1!+2!+⋯+10!的值。*/
//double fact(int i)
//{
//    if (i > 1)
//        return i * fact(i - 1);
//    else if (i == 1)
//        return 1;
//}
//#include <stdio.h>
//
//double fact(int n);
//
//int main(void)
//{
//    int i;
//    double sum;
//
//    sum = 0;
//    for (i = 1; i <= 10; i++)
//        sum = sum + fact(i);
//
//    printf("1!+2!+...+10! = %f\n", sum);
//    return 0;
//}

/*
本题要求实现一个求整数的逆序数的简单函数。

函数接口定义：
int reverse( int number );
其中函数reverse须返回用户传入的整型number的逆序数。
*/
//int reverse(int n)
//{
//    int sum = 0;
//    if (n > 0)
//    {
//        while (n > 0)
//        {
//            sum = sum * 10 + n % 10;
//            n /= 10;
//        }
//        return sum;
//    }
//    else
//    {
//        n = -n;
//        while (n > 0)
//        {
//            sum = sum * 10 + n % 10;
//            n /= 10;
//        }
//        return -sum;
//    }
//}

/*
本题要求实现一个计算两个数的最大公约数的简单函数。

函数接口定义：
int gcd( int x, int y );
其中x和y是两个正整数，函数gcd应返回这两个数的最大公约数。
*/
//int gcd(int x, int y)
//{
//    while (x % y != 0)
//    {
//        int c = x % y;
//        x = y;
//        y = c;
//    }
//    return y;
//}


/*
本题要求实现一个用选择法对整数数组进行简单排序的函数。

函数接口定义：
void sort( int a[], int n );
其中a是待排序的数组，n是数组a中元素的个数。该函数用选择法将数组a中的元素按升序排列，结果仍然在数组a中。
*/
//void sort(int a[], int n)
//{
//    for (int i = 0; i < n - 1; i++)
//    {
//        for (int j = i + 1; j < n; j++)
//        {
//            if (a[i] > a[j])
//            {
//                int temp = a[i];
//                a[i] = a[j];
//                a[j] = temp;
//            }
//        }
//    }
//}

/*
本题要求实现一个函数，对一个整数进行按位顺序输出。

函数接口定义：
void printdigits( int n );
函数printdigits应将n的每一位数字从高位到低位顺序打印出来，每位数字占一行。
*/
//void printdigits(int n)
//{
//    if (n / 10 > 0)
//        printdigits(n / 10);
//    printf("%d\n", n % 10);
//}


/*
描述
KiKi想知道一个n阶方矩是否为上三角矩阵，请帮他编程判定。上三角矩阵即主对角线以下的元素都为0的矩阵，主对角线为从矩阵的左上角至右下角的连线。

输入描述：
第一行包含一个整数n，表示一个方阵包含n行n列，用空格分隔。 (2≤n≤10)

从2到n+1行，每行输入n个整数（范围-231~231-1），用空格分隔，共输入n*n个数。

输出描述：
一行，如果输入方阵是上三角矩阵输出"YES"并换行，否则输出"NO"并换行。

示例1
输入：
3
1 2 3
0 4 5
0 0 6
复制
输出：
YES
*/
//#include <stdio.h>
//
//int main()
//{
//    int n = 0, flag = 0;
//    scanf("%d", &n);
//    int arr[10][10] = { 0 };
//    for (int i = 0; i < n; i++)
//    {
//        for (int j = 0; j < n; j++)
//        {
//            scanf("%d", &arr[i][j]);
//        }
//    }
//    for (int i = 1; i < n; i++)
//    {
//        for (int j = 0; j < i; j++)
//        {
//            if (arr[i][j] != 0)
//                flag = 1;
//        }
//    }
//    if (flag)
//        printf("NO");
//    else
//        printf("YES");
//    return 0;
//}


/*
描述
KiKi现在得到一个包含n*m个数的整数序列，现在他需要把这n*m个数按顺序规划成一个n行m列的矩阵并输出，请你帮他完成这个任务。
输入描述：
一行，输入两个整数n和m，用空格分隔，第二行包含n*m个整数（范围-231~231-1）。(1≤n≤10, 1≤m≤10)
输出描述：
输出规划后n行m列的矩阵，每个数的后面有一个空格。
示例1
输入：
2 3
1 2 3 4 5 6
复制
输出：
1 2 3
4 5 6
*/
//#include <stdio.h>
//
//int main()
//{
//    int n = 0, m = 0;
//    scanf("%d%d", &n, &m);
//    int arr[10][10] = { 0 };
//    for (int i = 0; i < n; i++)
//    {
//        for (int j = 0; j < m; j++)
//        {
//            scanf("%d", &arr[i][j]);
//            printf("%d ", arr[i][j]);
//        }
//        printf("\n");
//    }
//    return 0;
//}


/*
描述
KiKi有一个矩阵，他想知道转置后的矩阵（将矩阵的行列互换得到的新矩阵称为转置矩阵），请编程帮他解答。

输入描述：
第一行包含两个整数n和m，表示一个矩阵包含n行m列，用空格分隔。 (1≤n≤10,1≤m≤10)

从2到n+1行，每行输入m个整数（范围-231~231-1），用空格分隔，共输入n*m个数，表示第一个矩阵中的元素。

输出描述：
输出m行n列，为矩阵转置后的结果。每个数后面有一个空格。
示例1
输入：
2 3
1 2 3
4 5 6
复制
输出：
1 4
2 5
3 6
*/
//#include <stdio.h>
//
//int main()
//{
//    int n = 0, m = 0;
//    int i, j;
//    int arr[10][10] = { 0 };
//    scanf("%d%d", &n, &m);
//    for (i = 0; i < n; i++)
//    {
//        for (j = 0; j < m; j++)
//        {
//            scanf("%d", &arr[j][i]);
//        }
//    }
//    for (i = 0; i < m; i++)
//    {
//        for (j = 0; j < n; j++)
//        {
//            printf("%d ", arr[i][j]);
//        }
//        printf("\n");
//    }
//    return 0;
//}
#include <stdio.h>

int main()
{
    int n = 0, m = 0;
    int i, j;
    int a, b;
    int k = 0;
    int arr[10][10] = { 0 };
    char ch;
    scanf("%d%d", &n, &m);
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            scanf("%d", &arr[i][j]);
        }
    }
    scanf("%d", &k);
    for (i = k; i > 0; i--)
    {
        scanf("%c%d%d", &ch, &a, &b);
        if (ch == 'r')
        {
            for (j = 0; j < m; j++)
            {
                int temp = arr[a][j];
                arr[a][j] = arr[b][j];
                arr[b][j] = temp;
            }
        }
        else if (ch == 'c')
        {
            for (j = 0; j < n; j++)
            {
                int temp = arr[j][a];
                arr[j][a] = arr[j][b];
                arr[j][b] = temp;
            }
        }
    }
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}



//#include<stdio.h>
//int main()
//{
//	char ch;
//	while (1)
//	{
//		scanf("%c", &ch);
//		if (ch == 'r')
//			printf("hehe");
//		else
//			printf("haha");
//	}
//
//	return 0;
//}